package org.qpcr.community.project.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.web.crud.service.GenericReactiveCrudService;
import org.qpcr.community.project.model.entity.DataAnalysisExperimentalRecordsEntity;
import org.qpcr.community.project.model.entity.DataGroupExperimentalRecordsRelateEntity;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class DataGroupExperimentalRecordsRelateService  extends GenericReactiveCrudService<DataGroupExperimentalRecordsRelateEntity, String> {

    /**
     * 根据组别类型ID集合查询关联数据
     *
     * @param groupTypeIds 组别类型ID集合
     * @return 按组别类型ID分组的关联数据Map
     */
    public Mono<Map<String, List<DataGroupExperimentalRecordsRelateEntity>>> findRelateDataByGroupTypeIds(Collection<String> groupTypeIds) {
        // 使用基本的查询方法，先获取所有数据然后过滤
        return createQuery()
                .where()
                .in(DataGroupExperimentalRecordsRelateEntity::getGroupTypeId, groupTypeIds)
                .fetch()
                .collectList()
                .map(list -> {
                    Map<String, List<DataGroupExperimentalRecordsRelateEntity>> result = list.stream()
                            .collect(Collectors.groupingBy(
                                    DataGroupExperimentalRecordsRelateEntity::getGroupTypeId
                            ));
                    return result;
                });
    }

    public Mono<List<DataGroupExperimentalRecordsRelateEntity>> listByGroupIds(Collection<String> groupTypeIds) {
        return createQuery()
              .in(DataGroupExperimentalRecordsRelateEntity::getGroupTypeId, groupTypeIds)
              .fetch()
              .collectList();
    }

    public List<String> listRecordIdsByGroupTypeIdsSync(Collection<String> groupTypeIds) {
        return this.listRecordIdsByGroupTypeIds(groupTypeIds).block();
    }

    public Mono<List<String>> listRecordIdsByGroupTypeIds(Collection<String> groupTypeIds) {
        return createQuery()
            .in(DataGroupExperimentalRecordsRelateEntity::getGroupTypeId, groupTypeIds)
            .fetch()
            .map(DataGroupExperimentalRecordsRelateEntity::getRecordId)
            .collectList();
    }

    public Mono<List<DataGroupExperimentalRecordsRelateEntity>> findRelateDataByGroupTypeId(String groupTypeId) {
        return createQuery()
               .where(DataGroupExperimentalRecordsRelateEntity::getGroupTypeId, groupTypeId)
               .fetch()
               .collectList();
    }

    public Mono<Integer> saveBatch(Collection<DataGroupExperimentalRecordsRelateEntity> entities) {
        if (entities == null || entities.isEmpty()) {
            return Mono.just(0);
        }
        return Flux.fromIterable(entities)
                   .as(super::insert);
    }

    public Mono<Integer> remove(DataGroupExperimentalRecordsRelateEntity entity) {
        if (entity == null) {
            return Mono.just(0);
        }
        return createDelete()
            .is(DataGroupExperimentalRecordsRelateEntity::getGroupTypeId, entity.getGroupTypeId())
            .and()
            .is(DataGroupExperimentalRecordsRelateEntity::getRecordId, entity.getRecordId())
            .execute();
    }

    public Mono<List<String>> findAllBindRecordIds(String groupId) {
        return createQuery()
            .is(DataGroupExperimentalRecordsRelateEntity::getGroupId, groupId)
            .fetch()
            .map(DataGroupExperimentalRecordsRelateEntity::getRecordId)
            .collectList();
    }

    public List<String> findAllBindRecordIdsSync(String groupId) {
        return findAllBindRecordIds(groupId).block();
    }
}
